package com.zkane.service;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoCollection;
import com.zkane.domain.Address;
import com.zkane.domain.Employee;
import com.zkane.repository.EmpRepository;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

    /**
     * @author: keluosi@bicitech.cn
     * @review:
     * @date: 2018/8/13
     */
    @Service
    public class EmployeeService {

        @Autowired
        private EmpRepository empRepository;

        @Autowired
        private MongoClient client;

        /**
         * 测验MongoDB的事务回滚
         */
        public void save() {
            try (ClientSession clientSession = client.startSession()) {
                clientSession.startTransaction();
                Employee employee = new Employee();
                employee.setName("王五");
                employee.setAge(31);
                Address address = new Address();
                address.setCity("北京");
                address.setStreet("长安路");
                employee.setAddress(address);
                MongoCollection<Document> employeeCollection = client.getDatabase("test").getCollection("employee");
                employeeCollection.insertOne(clientSession, Document.parse(JSONObject.toJSONString(employee)));

                //int i = 1 / 0;

                employee = new Employee();
                employee.setName("赵六");
                employee.setAge(25);
                address = new Address();
                address.setCity("北京");
                address.setStreet("太升路");
                employee.setAddress(address);
                employeeCollection.insertOne(clientSession, Document.parse(JSONObject.toJSONString(employee)));

                commitWithRetry(clientSession);
            }

        }

    /**
     * 提交失败时，进行重新提交
     * @param clientSession
     */
    void commitWithRetry(ClientSession clientSession) {
        while (true) {
            try {
                clientSession.commitTransaction();
                System.out.println("Transaction committed");
                break;
            } catch (MongoException e) {
                // can retry commit
                if (e.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) {
                    System.out.println("UnknownTransactionCommitResult, retrying commit operation ...");
                    continue;
                } else {
                    System.out.println("Exception during commit ...");
                    throw e;
                }
            }
        }
    }
}
